#include "bmp.h"

int main(int argc, char const *argv[])
{
    //初始化lcd
    int lcd = open("/dev/fb0", O_RDWR);
    struct fb_var_screeninfo vinfo;
    //struct fb_fix_screeninfo finfo;
    ioctl(lcd, FBIOGET_VSCREENINFO, &vinfo);
    //ioctl(lcd, FBIOGET_FSCREENINFO, &finfo);
    int lcd_w = vinfo.xres;//错误点三：
    int lcd_h = vinfo.yres;
    int bpp   = vinfo.bits_per_pixel;//色深
    int screen_size = lcd_w * lcd_h * bpp/8;
    char *fb_mem = mmap(NULL, screen_size, PROT_WRITE, MAP_SHARED, lcd, 0);
    
    //打开BMP图片，获取格式头
    FILE *fp = fopen(argv[1], "rb");
    struct bitmap_header head;
    struct bitmap_info info;
    fread(&head, sizeof(head), 1, fp);
    fread(&info, sizeof(info), 1, fp);
    if(info.compression){
        struct rgb_quad quad;
        fread(&quad, sizeof(quad), 1, fp);
    }
    printf("图片规格：%d × %d [%d]\n", info.width, info.height, head.size);

    //将RGB中的数据读出来
    int rgb_size = head.size - sizeof(head) - sizeof(info);
    char *rgb_data = malloc(rgb_size);
    fread(rgb_data, rgb_size, 1, fp);

    // 计算BMP一行的真实大小
    int pad = (4 - (info.width * (info.bit_count/8)) %4) %4;
    int bmp_line_size = info.width * info.bit_count/8 + pad;//错误点一：混淆lcd与bmp的色深

    // 4. 妥当地显示图片
    for(int i = 0; i < info.height && i < lcd_h; i++){
        //lcd一行偏移量
        int lcd_offset = lcd_w * bpp/8 * i;//错误点二：忘记算入每个像素点的字节大小
        //mbp一行偏移量
        int rgb_offset = bmp_line_size * (info.height-1 - i);
        for(int j = 0; j < info.width && j < lcd_w; j++)
            memcpy(fb_mem + (bpp/8)*j + lcd_offset, 
            rgb_data + (info.bit_count/8)*j + rgb_offset, 
            (info.bit_count/8));
    }
    // 5. 释放资源
    free(rgb_data);
    munmap(fb_mem, screen_size);
    fclose(fp);
    close(lcd);
    return 0;
}